/**
 * 
 */
package org.t2.backstage.module.player;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.banish.sql.core.util.QuerySet;
import org.gaming.backstage.PageData;
import org.gaming.service.apidoc.annotation.ApiDocument;
import org.gaming.tool.DateTimeUtil;
import org.gaming.tool.ListMapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.t2.backstage.module.gameserver.model.GameChannel;
import org.t2.backstage.module.gameserver.service.GameChannelService;
import org.t2.backstage.module.player.model.FirstPayRemain;
import org.t2.backstage.module.player.query.PlayerCommonQuery;
import org.t2.backstage.module.player.service.FirstPayRemainService;
import org.t2.backstage.module.player.service.PlayerPayInServerService;
import org.t2.backstage.module.player.vo.FirstPayRemainVo;

/**
 * 付费用户留存
 */
@Controller
public class FirstPayRemainController {

	@Autowired
	private GameChannelService gameChannelService;
	@Autowired
	private FirstPayRemainService firstPayRemainService;
	@Autowired
	private PlayerPayInServerService playerPayInServerService;
	
	//留存数据
	@ApiDocument("请求玩家留存数据")
	@RequestMapping(value = "/firstPayRemain/data.auth")
	@ResponseBody
	public PageData<FirstPayRemainVo> data(PlayerCommonQuery query) {
		QuerySet querySet = new QuerySet();
		//渠道选择
		if(query.getChannels() != null && !query.getChannels().isEmpty()) {
			querySet.findInSet("channel_id", query.getChannels());
		}
		//服务器选择
		if(query.getServerUids() != null && !query.getServerUids().isEmpty()) {
			querySet.findInSet("server_uid", query.getServerUids());
		}
		//开始时间
		long startTime = query.getStartTime() * 1000L;
		if(startTime == 0) {
			startTime = DateTimeUtil.monthZeroMillis();
		}
		String startBorn = DateTimeUtil.formatMillis(DateTimeUtil.YYYYMMDD, startTime);
		querySet.addCondition("first_date >= ?", startBorn);
		//结束时间
		long endTime = query.getEndTime();
		if(endTime > 0) {
			String endBorn = DateTimeUtil.formatMillis(DateTimeUtil.YYYYMMDD, endTime * 1000L);
			querySet.addCondition("first_date <= ?", endBorn);
		}
		//留存看30天内的数据
		querySet.addCondition("day_count < ?", 30);
		querySet.formWhere();
		
		List<FirstPayRemain> playerRemains = firstPayRemainService.queryRemain(querySet);
		Map<Integer, Map<Long, List<FirstPayRemain>>> firstChannelMap = ListMapUtil.fillTwoListMap(playerRemains, FirstPayRemain::getFirstDate, FirstPayRemain::getChannelId);
		
		Map<String, FirstPayRemainVo> resultMap = new HashMap<>();
		
		for(Entry<Integer, Map<Long, List<FirstPayRemain>>> firstChannelEntry : firstChannelMap.entrySet()) {
			int first = firstChannelEntry.getKey();
			Map<Long, List<FirstPayRemain>> channelMap = firstChannelEntry.getValue();
			
			for(Entry<Long, List<FirstPayRemain>> channelEntry : channelMap.entrySet()) {
				long channelId = channelEntry.getKey();
				GameChannel gameChannel = gameChannelService.getEntity(0, channelId);
				String key = first + "_" + channelId;
				
				FirstPayRemainVo resultVo = new FirstPayRemainVo();
				resultVo.setFirstDate(first);
				if(gameChannel != null) {
					resultVo.setChannelInfo(gameChannel.getName() + "[" + channelId + "]");
				} else {
					resultVo.setChannelInfo("");
				}
                for(FirstPayRemain playerRemain : channelEntry.getValue()) {
                	if (playerRemain.getDayCount() <= 0) {
						resultVo.setDayBase(playerRemain.getPlayerCount());
						resultVo.setPlayerCount(playerRemain.getPlayerCount());
                	}
                }
                
                BigDecimal count = new BigDecimal("" + resultVo.getDayBase());
                
                for(FirstPayRemain playerRemain : channelEntry.getValue()) {
                	Field field = FirstPayRemainVo.getField("day" + playerRemain.getDayCount());
                	if(field == null) {
                		continue;
                	}
                	if(resultVo.getDayBase() <= 0) {
                		try {
							field.set(resultVo, "0.00%");
						} catch (Exception e) {
						}
                	} else {
                		try {
							String value = new BigDecimal("" + playerRemain.getPlayerCount())
									.divide(count, 2, RoundingMode.FLOOR).multiply(new BigDecimal(100)).toString()
									+ "%(" + playerRemain.getPlayerCount() + ")";
							field.set(resultVo, value);
						} catch (Exception e) {
						}
                	}
                }
                
                resultMap.put(key, resultVo);
			}
		}
		
		List<String> bornChannelKeys = new ArrayList<>(resultMap.keySet());
		Collections.sort(bornChannelKeys);
		
		List<FirstPayRemainVo> resultList = new ArrayList<>();
		for(String bornChannelKey : bornChannelKeys) {
			resultList.add(resultMap.get(bornChannelKey));
		}
		
		PageData<FirstPayRemainVo> pageData = new PageData<>();
		pageData.setCount(resultList.size());
		pageData.setData(resultList);
		return pageData;
	}
	
	@ApiDocument("手动触发当天付费留存数据统计")
	@RequestMapping(value = "/firstPayRemain/manual.auth")
	@ResponseBody
	public void manual() {
		playerPayInServerService.countServerRecharge();
		firstPayRemainService.countPayRemain(DateTimeUtil.currMillis() + DateTimeUtil.ONE_DAY_MILLIS);
	}
}
